#ifndef _ODN_PHYS_PHYSICALOBJECT_H
#define _ODN_PHYS_PHYSICALOBJECT_H

#include "odn_scene_SceneElement.h"
#include "odn_phys_Point.h"
#include "odn_phys_Collider.h"
#include "odn_phys_Bone.h"
#include "odn_util_Vector3D.h"

#include <cstring>
#include <cassert>

#define CONSTRAINT_ITERATIONS 1

namespace ouden
{
	namespace physics
	{
		
		//Forward declaration 
		class ODN_Collider;
		
		//Base class for all physical scene objects 
		class ODN_PhysicalObject : public ouden::scene::ODN_SceneElement
		{
			
		public:
			
			//Blank constructor creates empty model 
			ODN_PhysicalObject()		{}
			
			//Constructor to load model from file and set position 
			ODN_PhysicalObject(Vector3D Pos, std::string ModelName)		{}
			
			//Destructor 
			virtual ~ODN_PhysicalObject();
			
			//Update the object parts 
			virtual bool Update();
			
			//Update all of the constraints of the object, including bones, restrictions and collision detection 
			bool satisfyConstraints();
			
			//TODO: Work out a way to allow objects to be moved to a position 
			//Move points relative to point[0] 
			//virtual void moveTo(Vector3D Pos)		{}
			
			//Get the position of the object, which actually just returns the position of the first point 
			virtual Vector3D getPos()		{ assert(points[0]); return points[0]->pos; }
			
		protected:
			
			//Functions to add model parts 
			ODN_Point* addNewPoint(ODN_Point Point);
			ODN_Point* addExistingPoint(ODN_Point* Point) 				{ points.push_back(Point); return Point; }
			//ODN_DynamicPoint* addPoint(ODN_DynamicPoint* Point)			{ scene->addDynamicPoint(Point); points.push_back(Point); return Point;	}
			
			/*ODN_Collider* addCollider(ODN_Collider* Collider)		{ scene->addCollider 
				colliders.push_back(Collider);
				
				
			}*/
			
			//ODN_Bone* addBone(ODN_Bone* Bone);
			//... 
			
			
		private:
			
			std::vector<ODN_Point*> points;
			std::vector<ODN_Collider*> colliders;
			std::vector<ODN_Bone*> bones;
			//std::vector<ODN_Spring*> springs;
			//std::vector<ODN_Restriction*> restrictions;
			
		};
		
	} //namespace physics 
} //namespace ouden 

#endif //_ODN_PHYS_PHYSICALOBJECT_H 
